﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
#if UNITY_EDITOR
    using UnityEditor;
    using UnityEditor.Animations;
#endif
using UnityEngine;

namespace Gameplay.PVE
{
    public class AnimatorPlayer : MonoBehaviour
    {
#if UNITY_EDITOR
        private Animator animator;
#endif
        public List<string> actions = new List<string>
        {
            "StandAttack",
            "Skill",
            "SkillPassive",
            "SkillPassive1",
            "SkillPassive2",
            "SkillPassive3",
            "Over",
            "Roll",
        };

        public void Init()
        {
            #if UNITY_EDITOR
            animator = gameObject.GetOrAddComponent<Animator>();
            if (animator.runtimeAnimatorController == null)
            {
                UnityEngine.Object parent = PrefabUtility.GetCorrespondingObjectFromSource(gameObject);
                string path = AssetDatabase.GetAssetPath(parent);
                string root = path.Substring(0, path.LastIndexOf("/", StringComparison.Ordinal));

                RuntimeAnimatorController controller = null;
                List<AnimationClip> clips = new List<AnimationClip>();
                bool isNewController = false;
                foreach (string dirpath in Directory.GetFiles(root))
                {
                    if (dirpath.EndsWith(".anim"))
                    {
                        var clip = AssetDatabase.LoadAssetAtPath<AnimationClip>(dirpath);
                        clips.Add(clip);
                    }
                    else if (dirpath.Contains(name + ".controller") && dirpath.EndsWith(".controller"))
                    {
                        controller = AssetDatabase.LoadAssetAtPath<RuntimeAnimatorController>(dirpath);
                    }
                }

                if (controller == null)
                {
                    controller = AnimatorController.CreateAnimatorControllerAtPath(root + "/" + name + ".controller");
                    isNewController = true;
                }
                animator.runtimeAnimatorController = controller;
                if (isNewController)
                {
                    AnimatorControllerLayer m_layer = ((AnimatorController) controller).layers[0];
                    for (int i = 0; i < clips.Count; i++)
                    {
                        var clip = clips[i];
                        AnimatorStateMachine m_stateMachine = m_layer.stateMachine;
                        AnimatorState m_state = m_stateMachine.AddState(clip.name);
                        m_state.motion = clip;
                        
                    }
                    AssetDatabase.SaveAssets();
                }
            }
            actions = new List<string>();
            var overrides = new List<KeyValuePair<AnimationClip, AnimationClip>>();
            ((AnimatorOverrideController)animator.runtimeAnimatorController).GetOverrides(overrides);
            for (int i = 0; i < overrides.Count; i++)
            {
                if (overrides[i].Value != null)
                {
                    actions.Add(overrides[i].Value.name);
                }
            }
            #endif
        }

#if UNITY_EDITOR
        public void ChangeModelToDefault(GameObject gameObject)
        {
        
            var animator = gameObject.GetComponent<Animator>();
            if (animator)
            {
                var avatarPath = AssetDatabase.GetAssetPath(animator.avatar);
                var originGo = GameObject.Instantiate(AssetDatabase.LoadAssetAtPath<GameObject>(avatarPath));
                var originBoneRoot = originGo.transform.Find("Root");
                var boneRoot = gameObject.transform.Find("Root");
                if (boneRoot && originBoneRoot)
                {
                    var path = string.Empty;
                    ProcessChild(boneRoot, originBoneRoot, path);
                }
            }
        }

        private void ProcessChild(Transform target,Transform parent,string path)
        {
            for (int i = 0; i < parent.childCount; i++)
            {
                var child = parent.GetChild(i);
                var newPath = path + "/" + child.name;
                if (path == string.Empty)
                {
                    newPath = child.name;
                }
                var node = target.Find(newPath);
                if (node)
                {
                    node.localPosition = child.localPosition;
                    node.localEulerAngles = child.localEulerAngles;
                    node.localScale = child.localScale;
                    node.gameObject.SetActive(child.gameObject.activeSelf);
                }
                ProcessChild(target,child,newPath);
            }
        }
        
        private void OnDestroy()
        {
            ChangeModelToDefault(this.gameObject);
        }
#endif
    }
}

